﻿using System;
using System.Collections.Generic;
using GeoAPI.Geometries;
using NetTopologySuite.Algorithm;
using NetTopologySuite.Geometries;

namespace NetTopologySuite.Noding
{
	public class IteratedNoder : INoder
	{
		public IteratedNoder(IPrecisionModel pm)
		{
			this._li = new RobustLineIntersector
			{
				PrecisionModel = pm
			};
		}

		public int MaximumIterations
		{
			get
			{
				return this._maxIter;
			}
			set
			{
				this._maxIter = value;
			}
		}

		public IList<ISegmentString> GetNodedSubstrings()
		{
			return this._nodedSegStrings;
		}

		public void ComputeNodes(IList<ISegmentString> segStrings)
		{
			int[] array = new int[1];
			this._nodedSegStrings = segStrings;
			int num = 0;
			int num2 = -1;
			for (;;)
			{
				this.Node(this._nodedSegStrings, array);
				num++;
				int num3 = array[0];
				if (num2 > 0 && num3 >= num2 && num > this._maxIter)
				{
					break;
				}
				num2 = num3;
				if (num2 <= 0)
				{
					return;
				}
			}
			throw new TopologyException("Iterated noding failed to converge after " + num + " iterations");
		}

		private void Node(IList<ISegmentString> segStrings, int[] numInteriorIntersections)
		{
			IntersectionAdder intersectionAdder = new IntersectionAdder(this._li);
			MCIndexNoder mcindexNoder = new MCIndexNoder(intersectionAdder);
			mcindexNoder.ComputeNodes(segStrings);
			this._nodedSegStrings = mcindexNoder.GetNodedSubstrings();
			numInteriorIntersections[0] = intersectionAdder.NumInteriorIntersections;
		}

		public const int MaxIterations = 5;

		private readonly LineIntersector _li;

		private IList<ISegmentString> _nodedSegStrings;

		private int _maxIter = 5;
	}
}
